package people.paper.tv.activity.home.modual.sptt.view.impl;

import android.content.Context;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.skyworth.ui.define.SkyTextSize;
import com.skyworth.util.Util;

import java.lang.ref.WeakReference;
import java.util.Formatter;
import java.util.Locale;

import people.paper.tv.R;

public class VideoSeekBar extends FrameLayout {
    SeekBar currentBar, seekedSeekbar;
    private int progress = 0;
    private int maxProgress = 1;
    private int range = 1;// 快进快退幅度比例，根据总时间获得
    protected long total_time = 0; // 播放器在SHOW时没有发送总时间，在refresh的时候才会拿到总时间
    private long duration_time = 0;
    private int maxProcess = 100;
    private final static int DOT_DISMISS = 0;
    private final static int RESET_KEY_TIME = 1;
    private final static int CMD_DELAY = 2;
    private final static int HIDE_MSG = 3;
    MainHandler mainHandler;
    TextView timeTv;
    boolean isFirstKey = false;
    VideoLayout parentVideo;
    private StringBuilder mFormatBuilder;
    private Formatter mFormatter;
    protected TextView seekTimeTextV; // seek时间显示
    protected ImageView seekTimeImgV; // seek图片显示
    LinearLayout seekTimeLayout;
    ImageView playIv;
    View focus;

    private static class MainHandler extends Handler
    {

        private WeakReference<VideoSeekBar> seekbarBasic;

        public MainHandler(VideoSeekBar seekbarBasic)
        {
            super();
            this.seekbarBasic = new WeakReference<VideoSeekBar>(seekbarBasic);
        }

        @Override
        public void handleMessage(Message msg)
        {
            VideoSeekBar basicView = seekbarBasic.get();
            if (basicView == null)
            {
                return;
            }
            switch (msg.what)
            {
                case DOT_DISMISS:
//                    basicView.seekedSeekbar.setVisibility(View.INVISIBLE);
//                    basicView.seekedSeekbar.setProgress(basicView.currentBar.getProgress());
                    break;
                case RESET_KEY_TIME:
                    basicView.isResetKeyTime = true;
                    break;
                case CMD_DELAY:
                    basicView.sendCmd(msg.arg1,(KeyEvent)msg.obj);
                    break;
                case HIDE_MSG:
                    Log.d("VideoSeekBar", "--- setSeekBarShow HIDE_MSG---"+System.currentTimeMillis());
                    basicView.setBarShow(false, true);
                    this.removeMessages(HIDE_MSG);
                    break;
                default:
                    break;
            }
        }
    }

    public VideoSeekBar(@NonNull Context context) {
        super(context);
        mFormatBuilder = new StringBuilder();
        mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
        mainHandler = new MainHandler(this);
        initView();
    }

    private void initView()
    {
        focus = new View(getContext());
        addView(focus);
        focus.setFocusable(true);
        focus.setFocusableInTouchMode(true);
        focus.setOnKeyListener(onKeyListener);
        focus.setVisibility(GONE);

        currentBar = new SeekBar(getContext());
        currentBar.setProgress(0);
        currentBar.setFocusable(false);
        currentBar.setFocusableInTouchMode(true);
        currentBar.requestFocusFromTouch();

        seekedSeekbar = new SeekBar(getContext());
        seekedSeekbar.setProgress(0);
        seekedSeekbar.setFocusable(true);
        seekedSeekbar.setFocusableInTouchMode(false);
        seekedSeekbar.requestFocus();
        seekedSeekbar.setOnKeyListener(onKeyListener);

        LayoutParams lp = new LayoutParams(Util.Div(1920), Util.Div(3));
        lp.topMargin = Util.Div(55);
        addView(seekedSeekbar, lp);
        addView(currentBar, lp);
        changeSeekbarStyle();

        timeTv = new TextView(getContext());
        LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.RIGHT);
        layoutParams.topMargin = Util.Div(65);
        layoutParams.rightMargin = Util.Div(30);
        addView(timeTv, layoutParams);


        seekTimeLayout = new LinearLayout(getContext());
        seekTimeLayout.setLayoutParams(new LayoutParams(Util.Div(165), Util.Div(52)));
        seekTimeLayout.setOrientation(LinearLayout.VERTICAL);
        seekTimeLayout.setGravity(Gravity.CENTER_VERTICAL);

        seekTimeTextV = new TextView(getContext());
        seekTimeImgV = new ImageView(getContext());
        seekTimeImgV.setImageResource(R.mipmap.seek_img);

        seekTimeLayout.addView(seekTimeTextV);
        seekTimeLayout.addView(seekTimeImgV);
        addView(seekTimeLayout);

        seekTimeTextV.setSingleLine(true);
        seekTimeTextV.setTextColor(getResources().getColor(R.color.title_focus));
        seekTimeTextV.setTextSize(Util.Dpi(SkyTextSize.t_2));
        seekTimeTextV.setGravity(Gravity.CENTER);
        LinearLayout.LayoutParams seekTimeTextVlps = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        seekTimeTextVlps.weight = 1;
        seekTimeTextV.setLayoutParams(seekTimeTextVlps);
        seekTimeTextV.setBackgroundColor(getResources().getColor(R.color.seek_time_bg));

        playIv = new ImageView(getContext());
        playIv.setImageResource(R.mipmap.seekbar_play);
        LayoutParams ivParam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        ivParam.topMargin = Util.Div(80);
        ivParam.leftMargin = Util.Div(30);
//        addView(playIv, ivParam);
//        setSeekBarShow();
        setBarShow(false, false);
    }

    public void setParentVideo(VideoLayout parent){
        parentVideo = parent;
    }

    public void getFocus(){
        setVisibility(VISIBLE);
        bringToFront();
        setBarShow(!isFirstKey, true);
    }

    public OnKeyListener onKeyListener = new OnKeyListener()
    {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event)
        {
            if (KeyEvent.ACTION_UP == event.getAction())
            {
                return false;
            }
            Log.d("VideoSeekBar", "--- onKey ---"+keyCode);
            switch (keyCode)
            {
                case KeyEvent.KEYCODE_BACK:
                    if(mainHandler != null && mainHandler.hasMessages(CMD_DELAY))
                    {
                        mainHandler.removeMessages(CMD_DELAY);
                        mainHandler.removeMessages(HIDE_MSG);
                    }
                    stopRefresh = false;
                    setBarShow(false, false);
                    return parentVideo.onKey(v, keyCode, event);
                case KeyEvent.KEYCODE_ENTER:
                case KeyEvent.KEYCODE_DPAD_CENTER:
                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                    setPlayStatus();
                    return true;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    // 如果是视频播放器才移动，音乐播放器发命令，切歌
                    keyCode = KeyEvent.KEYCODE_DPAD_LEFT;
                    stopRefresh = true;
                    progress = seekedSeekbar.getProgress();
                    int diff = getAccelerationSpeed(keyCode);
                    int setProgress = (progress - diff) > 0 ? (progress - diff) : 0;
                    seekedSeekbar.setProgress(setProgress);
                    setSeekBarShow();
                    setFsTime(setProgress, ProcessToTime(setProgress));
                    if (seekedSeekbar.getVisibility() == View.VISIBLE)
                    {
                        if (mainHandler.hasMessages(CMD_DELAY))
                        {
                            mainHandler.removeMessages(CMD_DELAY);
                        }
                        Message msg = new Message();
                        msg.what = CMD_DELAY;
                        msg.arg1 = keyCode;
                        msg.obj = event;
                        mainHandler.sendMessageDelayed(msg, 1000);
                        mainHandler.removeMessages(DOT_DISMISS);
                        mainHandler.sendEmptyMessageDelayed(DOT_DISMISS, 8000);
                    } else
                    {
                        mainHandler.removeMessages(DOT_DISMISS);
                    }
                    return true;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    keyCode = KeyEvent.KEYCODE_DPAD_RIGHT;
                    stopRefresh = true;
                    progress = seekedSeekbar.getProgress();
                    int diff1 = getAccelerationSpeed(keyCode);
                    int setProgress1 = (progress + diff1) < (maxProcess - 1) ? (progress + diff1)
                            : (maxProcess - 1);
                    seekedSeekbar.setProgress(setProgress1);
                    setFsTime(setProgress1, ProcessToTime(setProgress1));
                    setSeekBarShow();
                    if (seekedSeekbar.getVisibility() == View.VISIBLE)
                    {

                        if (mainHandler.hasMessages(CMD_DELAY))
                        {
                            mainHandler.removeMessages(CMD_DELAY);
                        }
                        Message msg = new Message();
                        msg.what = CMD_DELAY;
                        msg.arg1 = keyCode;
                        msg.obj = event;
                        mainHandler.sendMessageDelayed(msg, 1000);
                        mainHandler.removeMessages(DOT_DISMISS);
                        mainHandler.sendEmptyMessageDelayed(DOT_DISMISS, 8000);
                    } else
                    {
                        mainHandler.removeMessages(DOT_DISMISS);
                    }
                    return true;
                case KeyEvent.KEYCODE_DPAD_UP:
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    parentVideo.setListVisible(true);
                    return true;
            }
            return false;
        }
    };

    public void sendCmd(int keyCode,KeyEvent event)
    {
        if (keyCode == KeyEvent.KEYCODE_BACK)
        {
            // 进度条上的返回命令
            // seekListener.onSeekBarKeyDown(keyCode);
            if(mainHandler != null && mainHandler.hasMessages(CMD_DELAY))
            {
                mainHandler.removeMessages(CMD_DELAY);
                Log.d("VideoSeekBar", "--- mainHandler.removeMessages(CMD_DELAY) ---");
            }
        } else if ((keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER
                || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)) {
            if (mainHandler.hasMessages(CMD_DELAY))
            {
                mainHandler.removeMessages(CMD_DELAY);
            }
            seekToPosition();
        }
        isResetKeyTime = true;
        stopRefresh = false;
    }

    public void seekToPosition()
    {
        if(seekedSeekbar.getProgress() < 0)
            seekedSeekbar.setProgress(0);
        Log.d("VideoSeekBar", "--- seekToPosition) ---"+seekedSeekbar.getProgress()
                +"; "+seekedSeekbar.getProgress()*total_time/100+";getTime: "+getTime(seekedSeekbar.getProgress()*total_time/100)+"; "+total_time);
        currentBar.setProgress(seekedSeekbar.getProgress());
        callBack.seek(seekedSeekbar.getProgress()*total_time/100);
    }

    private String ProcessToTime(int pos)
    {
        return getTime((long) ProcessPosToTime(pos));
    }

    private float ProcessPosToTime(float pos)
    {
        if (pos > maxProcess)
        {
            pos = maxProcess;
        }
        return (pos * total_time / maxProcess);
    }

    private boolean isResetKeyTime = true;
    private long mFirstKeyTime = 0;
    private int direct = 0;

    private int getAccelerationSpeed(int keyCode)
    {
        if (isResetKeyTime || direct != keyCode)
        {
            direct = keyCode;
            mFirstKeyTime = System.currentTimeMillis();
            isResetKeyTime = false;
        }
        float Dvalue = Math.abs(System.currentTimeMillis() - mFirstKeyTime);
        int step = (int) ((Dvalue % 100000) / 1000);
        maxProgress = seekedSeekbar.getMax();
        range = maxProgress / 200;
        if (range < 1)
        {
            range = 1;
        }
        if (mainHandler.hasMessages(RESET_KEY_TIME))
        {
            mainHandler.removeMessages(RESET_KEY_TIME);
        }
        mainHandler.sendEmptyMessageDelayed(RESET_KEY_TIME, 300);
        switch (step)
        {
            case 0:
                return 1 * range;
            case 1:
                return 3 * range;
            case 2:
                return 6 * range;
            case 3:
                return 8 * range;
            case 4:
                return 12 * range;
            default:
                return 20 * range;
        }
    }

    /**
     * 概述：左右和飞梭按键，第一次按键出现SeekBar，以及决定确定按键是暂停还是定位 <br/>
     *
     * @date 2014-1-13
     */
    public void setSeekBarShow()
    {
        if (isFirstKey)
        {
            setBarShow(true, true);
        }
        Log.d("VideoSeekBar", "--- setSeekBarShow ---"+isFirstKey+"; "+System.currentTimeMillis());
        if (mainHandler.hasMessages(HIDE_MSG))
            mainHandler.removeMessages(HIDE_MSG);
        mainHandler.sendEmptyMessageDelayed(HIDE_MSG, 8000);
    }

    public void setBarShow(boolean visibility, boolean needFocus){
        if(visibility){
            currentBar.setVisibility(VISIBLE);
            seekedSeekbar.setVisibility(VISIBLE);
            timeTv.setVisibility(VISIBLE);
            seekTimeLayout.setVisibility(VISIBLE);
            seekTimeTextV.setVisibility(VISIBLE);
            seekTimeImgV.setVisibility(VISIBLE);
            playIv.setVisibility(VISIBLE);
            seekedSeekbar.requestFocus();
            focus.setVisibility(GONE);
        }else {
            if(needFocus && parentVideo.isBigVideo){
                focus.setVisibility(VISIBLE);
                focus.requestFocus();
            }
            currentBar.setVisibility(INVISIBLE);
            seekedSeekbar.setVisibility(INVISIBLE);
            timeTv.setVisibility(INVISIBLE);
            seekTimeLayout.setVisibility(INVISIBLE);
            seekTimeTextV.setVisibility(INVISIBLE);
            seekTimeImgV.setVisibility(INVISIBLE);
            playIv.setVisibility(INVISIBLE);
        }
        isFirstKey = !visibility;
    }

    public void setPlayStatus(){
        callBack.playOrPause();
    }

    private Drawable barbg;
    private Drawable barbg_tans;
    private Drawable current_bar;
    private void createDrawable()
    {
        barbg_tans = getResources().getDrawable(R.mipmap.transparent);
        barbg = getResources().getDrawable(R.mipmap.std_player_seekbg);
        current_bar = getResources().getDrawable(R.mipmap.std_player_current_process);
        setSeekbarDrawable();
    }

    private void setSeekbarDrawable()
    {
        Drawable[] layers = new Drawable[2];
        layers[1] = new ClipDrawable(current_bar, Gravity.LEFT, ClipDrawable.HORIZONTAL);
        layers[0] = barbg;
        LayerDrawable seekbarBg = new LayerDrawable(layers);
        currentBar.setProgressDrawable(seekbarBg);

        Drawable[] layers_buffer = new Drawable[2];
        layers_buffer[1] = new ClipDrawable(barbg_tans, Gravity.LEFT, ClipDrawable.HORIZONTAL);
        layers_buffer[0] = barbg_tans;
        LayerDrawable bufferseekdotbarBg = new LayerDrawable(layers_buffer);
        seekedSeekbar.setProgressDrawable(bufferseekdotbarBg);
    }

    public void changeSeekbarStyle()
    {
        createDrawable();
        seekedSeekbar.setPadding(0, 1, 0, 1);

        currentBar.setThumb(null);
        seekedSeekbar.setThumb(getResources().getDrawable(R.mipmap.transparent));
    }

    ISPTTViewCallBack callBack;
    public void setParentViewCallback(ISPTTViewCallBack c) {
        this.callBack = c;
    }

    boolean stopRefresh = false;
    boolean exit = false;
    public void refreshDuration(long total, long duration){
        total_time = total;
        duration_time = duration;
        timeTv.setText(""+getTime(duration)+"/"+getTime(total));
        Log.d("VideoSeekBar", "--- refreshDuration) ---"+total_time+"; "+duration+"; "+progress);
        if(!stopRefresh && total > 0){
            int progress = (int) (duration*100/total);
            Log.d("VideoSeekBar", "--- refreshDuration) ---"+total_time+"; "+duration+"; "+progress+exit);
            seekedSeekbar.setProgress(progress);
            currentBar.setProgress(seekedSeekbar.getProgress());
            setFsTime(progress, getTime(duration));
            if(progress >= 99){
                if(!exit)
                    parentVideo.exitFullScreen();
                exit = true;
            }else {
                exit = false;
            }
        }
    }

    public String getTime(long timeMs) {
        int totalSeconds = (int)(timeMs / 1000);
        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;
        mFormatBuilder.setLength(0);
        return mFormatter.format("%02d:%02d:%02d", hours, minutes, seconds).toString();
    }

    public void setFsTime(int position, String str)
    {
        int screenWidth = Util.Div(1920);
        // 时间飘窗的宽度
//        float _fs_width = Util.Div(30);
        float _fs_width = Util.Div(165);

        // 每次增加的距离，即视频播放的时间点距离，跳转到的播放点
        float x = (float) (position * screenWidth / (double) maxProcess);

        if (x <= _fs_width) // 播放时间点小于飘窗的宽度的时候，飘窗固定在0的位置，只是移动指针到播放的位置
        {
            if (x >= 0)// 中间位置，播放指针移动即可
            {
                seekTimeImgV.setX(x - _fs_width / 2.0f);
                seekTimeLayout.setX(0);
                Log.d("VideoSeekBar", "--- setFsTime) ---"+x+"; "+_fs_width+"; "+position);
            } else
            // 最左边的位置，固定在做左边
            {
                x = 0;
                seekTimeImgV.setX(-_fs_width / 2.0f);
                seekTimeLayout.setX(0);
            }
        } else if (x <= screenWidth)// 播放时间点还未接近到总的屏幕宽度的时候
        {
            seekTimeImgV.setX(_fs_width / 2.0f);
            seekTimeLayout.setX(x - _fs_width);
        } else
        // 播放时间点超过总的屏幕宽度的时候，固定到最后的位置
        {
            seekTimeImgV.setX(_fs_width / 2.0f);
            seekTimeLayout.setX(screenWidth - _fs_width);
        }

        // 位置进行最后的调整
        if (position >= maxProcess - 1)
        {
            seekTimeImgV.setX(_fs_width / 2.0f);
            seekTimeLayout.setX(screenWidth - _fs_width);
        } else if (position <= 1)
        {
            seekTimeImgV.setX(-_fs_width / 2.0f);
            seekTimeLayout.setX(0);
        }
        seekTimeTextV.setText(str);
        seekTimeLayout.setVisibility(View.VISIBLE);
        seekTimeLayout.requestLayout();
        // Refresh the seekImage hide time
//        autoSeekImg();
    }
}
